import 'dart:collection';

import 'package:winkai/db/dao/msg_dao.dart';
import 'package:winkai/service/api_service.dart';
import 'package:winkai/dio/base_result.dart';
import 'package:winkai/entity/msg_constant.dart';
import 'package:winkai/entity/mse_rpy_rsp.dart';
import 'package:winkai/ext/ext.dart';
import 'package:winkai/main.dart';
import 'package:winkai/service/msg_service.dart';

///消息接收管理
class MsgReceiveHelper {
  static MsgReceiveHelper? _singleton;

  factory MsgReceiveHelper() {
    _singleton ??= MsgReceiveHelper._();
    return _singleton!;
  }

  MsgReceiveHelper._();

  ///正在检查回答的消息
  final List<String> _checkReplyList = [];

  void checkMsgReplay(MsgInfo messageInfo) {
    var serviceMsgId = messageInfo.msg.serviceMsgId;
    var serviceNextMsgIds = messageInfo.msg.serviceNextMsgIds?.toStringList;

    ///检查消息是否回复，未回复开始手动拉取恢复
    if (!isReply(messageInfo) &&
        serviceMsgId?.isNotEmpty == true &&
        serviceNextMsgIds?.isNotEmpty == true) {
      MsgReceiveHelper().startReceiveMsg(
        messageInfo,
        messageInfo.session.id,
        serviceMsgId!,
        serviceNextMsgIds!,
      );
    }
  }

  ///是否回复
  bool isReply(MsgInfo? messageInfo) {
    if (messageInfo?.msg.contentType == MsgContentType.waitAnswer) {
      return false;
    }
    return true;
  }

  ///开始接收消息回答
  void startReceiveMsg(
    MsgInfo? waitAnswerMsg,
    String sessionId,
    String serviceMessageId,
    List<String> serviceNextMessageIds, {
    int start = 0,
  }) async {
    if ((!_checkReplyList.contains(serviceMessageId) && start == 0) ||
        start > 0) {
      if (!_checkReplyList.contains(serviceMessageId)) {
        _checkReplyList.add(serviceMessageId);
      }

      void tryNext() async {
        if (start < 5) {
          await Future.delayed(const Duration(milliseconds: 1500));
          startReceiveMsg(
            waitAnswerMsg,
            sessionId,
            serviceMessageId,
            serviceNextMessageIds,
            start: start + 1,
          );
        } else {
          if (waitAnswerMsg != null) {
            var message = waitAnswerMsg.msg;
            await getIt<MsgService>().insertOrUpdateMsg(
              message.content,
              sessionId: message.sessionId,
              userId: message.userId,
              msgId: message.id,
              sendFailReason: message.sendFailReason,
              serviceMsgId: message.serviceMsgId,
              serviceNextMessageIds: message.serviceNextMsgIds.toStringList,
              status: MsgStatus.failure,
              contentType: message.contentType,
              isPrivateChat: message.isPrivateChat,
              isCreate: false,
            );
          }
          _checkReplyList.remove(serviceMessageId);
        }
      }

      try {
        var results = await Future.wait<BaseResult<MsgRpyRsp>>(
          serviceNextMessageIds
              .map((e) => ApiService().getMsgReply(e))
              .toList(),
        );
        LinkedHashMap<String, MsgRpyRspAnswer> answerMap =
            LinkedHashMap<String, MsgRpyRspAnswer>();
        for (var result in results) {
          var answer = result.data?.answer;
          if (result.isSucceed &&
              answer != null &&
              answer.content?.isNotEmpty == true) {
            answerMap[result.data?.msgId ?? ''] = answer;
          }
        }
        if (answerMap.length == serviceNextMessageIds.length) {
          if (waitAnswerMsg != null) {
            await getIt<MsgService>().deleteMsg(waitAnswerMsg);
          }
          for (var entries in answerMap.entries) {
            var messageId = entries.key;
            var answer = entries.value;
            await getIt<MsgService>().receiveMsgAnswer(
                sessionId: sessionId,
                serviceMessageId: messageId,
                answer: answer);
          }
          _checkReplyList.remove(serviceMessageId);
        } else {
          tryNext();
        }
      } catch (e) {
        tryNext();
      }
    }
  }
}
